#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define BUFF_SIZE 256

int verbose = 0;

// Questa funzione calcola la copertura delle sottostrutture con cui subdue comprime il grafo originario
void coverage(char* filename_g, char* filename_cmp);

// Questo programma necessita dei seguenti parametri:
// - "-v" (opzionale) per abilitare la modalita' verbose
// - il file .g (obbligatorio)
// - il file .cmp (obbligatorio)
int main(int argc, char* argv[])
{
	// Queste sono le variabili che conterranno i percorsi dei files dati in input
	char file_cmp[BUFF_SIZE], file_g[BUFF_SIZE];

	// Viene salvato il tempo di calendario all'inizio dell'esecuzione per poterne calcolare la durata
	time_t inizio = time(NULL);

	// Se vengono passati 4 parametri e l'ultimo e' verbose viene attivata tale modalita'
	if (argc == 4 && !strcmp(argv[1],"-v"))
		verbose=1;
	else if (argc != 3 )
	{
		fprintf(stderr, "Usage: %s [-v] <file.g> <file.g.cmp>", argv[0]);
		exit(EXIT_FAILURE);
	}

	// Vengono settati i percorsi agendo sulle stringhe
	strcpy(file_g, argv[verbose+1]);
	strcpy(file_cmp, argv[verbose+2]);

	char *lastslash = strrchr(file_g, '/');
	if (!lastslash)
	{
		sprintf(file_g, "./%s", argv[verbose+1]);
	}
	lastslash = strrchr(file_cmp, '/');
	if (!lastslash)
	{
		sprintf(file_cmp, "./%s", argv[verbose+2]);
	}

	// La copertura viene effettivamente lanciata
	coverage(file_g, file_cmp);

	// Viene salvato il tempo di calendario alla fine dell'esecuzione
	time_t fine = time(NULL);

	// Viene scritta la durata dell'esecuzione
	printf("\nIl calcolo della copertura ha richiesto circa %d secondi\n", (int)difftime(fine, inizio));

	return 0;
}

void coverage(char* filename_g, char * filename_cmp)
{
	// Variabili per le dimensioni dei grafi originale e compresso
	int size_g = 0, size_cmp = 0;

	// Vengono aperti i files dati in input
	FILE *file_g = fopen ( filename_g, "r" );
	FILE *file_cmp = fopen ( filename_cmp, "r" );

	// Buffer per memorizzare le righe dei files letti
	char buffer[BUFF_SIZE];

	// Controllo dell'esistenza dei files
	if (file_g == NULL)
	{
		if(verbose) printf("Il file %s non esiste\n", filename_g);
	}
	else
	{
		if(verbose) printf("Il file %s e' stato caricato\n", strrchr(filename_g, '/')+1);
	}
	if (file_cmp == NULL)
	{
		if(verbose) printf("Il file %s non esiste\n", filename_cmp);
	}
	else
	{
		if(verbose) printf("Il file %s e' stato caricato\n", strrchr(filename_cmp, '/')+1);
	}

	// Viene scansionato il file .g riga per riga alla ricerca di nodi ed archi
	while (fgets(buffer, sizeof(buffer), file_g))
	{
		// Si discrimina sulla prima lettera di ogni riga
		if (buffer[0] == 'v' || buffer[0] == 'u' || buffer[0] == 'd' || buffer[0] == 'e')
		{
			// Viene eventualmente incrementata la dimesione (norma) del file .g
			size_g++;
		}
	}
	// Chiusura del file e stampa del risultato
	fclose(file_g);
	if(verbose) printf("\nLa dimensione del grafo %s e' %d\n", strrchr(filename_g, '/')+1, size_g);

	// Viene scansionato il file .g.cmp
	while (fgets(buffer, sizeof(buffer), file_cmp))
	{
		// Viene incrementata la sua dimensione solo in presenza di archi oppure di nodi che non sono sottostrutture
		if (buffer[0] == 'v' || buffer[0] == 'u' || buffer[0] == 'd' || buffer[0] == 'e')
		{
			int i = 0;
			while (buffer[i] && buffer[i] != 'S')
				i++;
			if (!(buffer[i] == 'S' && buffer[i+1] == 'U' && buffer[i+2] == 'B' && buffer[i+3] == '_'))
				size_cmp++;
		}
	}
	// Viene chiuso il file e stampata la norma del grafo compresso senza contare le sottostrutture
	// Ovvero vengono presi in considerazione soltanto archi e nodi non inseriti in alcuna sottostruttura
	fclose(file_cmp);
	if(verbose) printf("\nIl numero di elementi di %s persi durante la compressione e' %d\n", strrchr(filename_g, '/')+1, size_cmp);

	// Viene ritornato il valore della copertura come
	// differenza tra la norma del grafo originale
	// ed il numero di archi e nodi non presenti nelle sottostrutture
	// fratto la norma del grafo originario
	printf("\nLa copertura e' del %3.3f %%\n", ((float)(size_g - size_cmp)/size_g)*100);
}
